package com.tdk.common.util

import android.util.Log
import java.util.Arrays

object ByteUtil {
    private const val TAG = "ByteUtil"
    private const val CMD_HEAD = 4

    /**
     * @return packed bytes
     * @Des: pack bytes as a data package
     * 0xFF 0xF6 len(2bytes) + content
     */
    fun packBytes(bytes: ByteArray): ByteArray {
        val retBytes = ByteArray(bytes.size + CMD_HEAD)
        retBytes[0] = 0xFF.toByte()
        Log.d(TAG, "packBytes: retBytes[0]=${retBytes[0]}")
        retBytes[1] = 0xF6.toByte()
        Log.d(TAG, "packBytes: retBytes[1]=${retBytes[1]}")
        retBytes[2] = (bytes.size shr 8).toByte()
        Log.d(TAG, "packBytes: retBytes[2]=${retBytes[2]}")
        retBytes[3] = bytes.size.toByte()
        Log.d(TAG, "packBytes: retBytes[3]=${retBytes[3]}")
        for (i in bytes.indices) {
            retBytes[CMD_HEAD + i] = bytes[i]
        }
        Log.d("ByteUtil", "packBytes: " + Arrays.toString(retBytes))
        return retBytes
    }

    /**
     * @return packed bytes of heart
     * @Des: pack bytes as a data package
     * 0xFF 0xF7 0xE8 0x10
     */
    fun packHeartBytes(): ByteArray {
        val retBytes = ByteArray(CMD_HEAD)
        retBytes[0] = 0xFF.toByte()
        retBytes[1] = 0xF7.toByte()
        retBytes[2] = 0xE8.toByte()
        retBytes[3] = 0x10.toByte()
        return retBytes
    }

    /**
     * @return list of bytes
     * @Des: parse bytes one by one
     */
    fun parseBytes(bytes: ByteArray): List<ByteArray> {
        val retList: MutableList<ByteArray> = ArrayList()
        parseOne(bytes, retList)
        return retList
    }

    private fun parseOne(bytes: ByteArray, retList: MutableList<ByteArray>) {
        Log.d("TAG", "parseOne: " + Arrays.toString(bytes))
        if (bytes.size < CMD_HEAD) {
            return
        }
        if (bytes[0] == 0xFF.toByte() && bytes[1] == 0xF6.toByte()) {
            val len = bytes[2].toInt() and 0xFF shl 8 or (bytes[3].toInt() and 0xFF)
            if (bytes.size < len + CMD_HEAD) {
                return
            }
            val temp = ByteArray(len)
            if (len == CMD_HEAD) {
//                if (bytes[4] == 0xFF.toByte() && bytes[5] == 0xF7.toByte() && bytes[6] == 0xE8.toByte() && bytes[7] == 0x10.toByte()) {
//                    listener.onHeardBeat()
//                }

                return
            } else {
                for (i in 0 until len) {
                    temp[i] = bytes[CMD_HEAD + i]
                }
                retList.add(temp)

            }
            val lastLen = len + CMD_HEAD
            if (lastLen < bytes.size) {
                val temps = ByteArray(bytes.size - lastLen)
                for (i in temps.indices) {
                    temps[i] = bytes[i + lastLen]
                }
                parseOne(temps, retList)
            }
        }
    }
}